package com.ym.livedemo

import android.app.Activity
import android.app.Service
import android.content.Context
import android.content.Intent
import android.util.Log
import android.view.View
import androidx.fragment.app.Fragment
import com.google.gson.Gson
import com.ym.livedemo.Internals.createIntent
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.logging.HttpLoggingInterceptor

fun getHttpLoggingInterceptor(): HttpLoggingInterceptor {
    val loggingInterceptor = HttpLoggingInterceptor()
    loggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
    return loggingInterceptor
}

fun <T> CoroutineScope.rxLaunch(init: CoroutineBuilder<T>.() -> Unit) {
    val result = CoroutineBuilder<T>().apply(init)
    val coroutineExceptionHandler = CoroutineExceptionHandler { _, exception ->
        result.onError?.invoke(exception)
    }
    launch(coroutineExceptionHandler) {
        val res: T? = result.onRequest?.invoke()
        res?.let {
            result.onSuccess?.invoke(it)
        }
    }
}

class CoroutineBuilder<T> {
    var onRequest: (suspend () -> T)? = null
    var onSuccess: ((T) -> Unit)? = null
    var onError: ((Throwable) -> Unit)? = null
}


fun toRequestBody(any: Any): RequestBody {
    val json = toJson(any)
    return json.toRequestBody("application/json; charset=utf-8".toMediaTypeOrNull())
}

fun toJson(any: Any): String = Gson().toJson(any)

fun loge(msg: String) {
    Log.e("TAG", msg)
}

inline fun <reified T : Activity> Context.startActivity(vararg params: Pair<String, Any>) {
    Internals.internalStartActivity(this, T::class.java, params)
}

inline fun <reified T : Activity> Fragment.startActivity(vararg params: Pair<String, Any>) {
    Internals.internalStartActivity(activity!!, T::class.java, params)
}

inline fun <reified T : Activity> Activity.startActivityForResult(
    requestCode: Int,
    vararg params: Pair<String, Any>
) {
    Internals.internalStartActivityForResult(this, T::class.java, requestCode, params)
}

inline fun <reified T : Activity> Fragment.startActivityForResult(
    requestCode: Int,
    vararg params: Pair<String, Any>
) {
    startActivityForResult(createIntent(activity!!, T::class.java, params), requestCode)
}

inline fun <reified T : Service> Context.startService(vararg params: Pair<String, Any>) {
    Internals.internalStartService(this, T::class.java, params)
}

inline fun <reified T : Service> Fragment.startService(vararg params: Pair<String, Any>) {
    Internals.internalStartService(activity!!, T::class.java, params)
}

inline fun <reified T : Any> Context.intentFor(vararg params: Pair<String, Any?>): Intent {
    return createIntent(this, T::class.java, params)
}

inline fun <reified T : Any> Fragment.intentFor(vararg params: Pair<String, Any?>): Intent {
    return createIntent(activity!!, T::class.java, params)
}

fun View.makeVisible() {
    visibility = View.VISIBLE
}

fun View.makeInVisible() {
    visibility = View.INVISIBLE
}

fun View.makeGone() {
    visibility = View.GONE
}